#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>

using namespace std;

typedef websocketpp::server<websocketpp::config::asio> websocketsvr;
typedef websocketsvr::message_ptr message_ptr;

using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;

void print(const std::string &str)
{
    std::cout << str << std::endl;
}

// 处理http请求的回调函数 返回⼀个html欢迎⻚⾯
void OnHttp(websocketsvr *server, websocketpp::connection_hdl hdl)
{
    cout << "处理Http请求" << endl;
    websocketsvr::connection_ptr con = server->get_con_from_hdl(hdl);
    cout << "body:" << con->get_request_body() << endl;
    websocketpp::http::parser::request req = con->get_request();
    cout << "method:" << req.get_method() << endl;
    cout << "uri:" << req.get_uri() << endl;
    stringstream ss;
    ss << "<!doctype html><html><head>"
       << "<title>hello websocket</title><body>"
       << "<h1>hello websocketpp</h1>"
       << "</body></head></html>";
    con->set_body(ss.str());
    con->set_status(websocketpp::http::status_code::ok);
    //设置定时器，毫秒，任务
    websocketsvr::timer_ptr tp = con->set_timer(5000,bind(print,"xiaoduantui"));
    tp->cancel();   //定时任务取消会导致任务立即被执行
}

// websocket连接成功的回调函数
void OnOpen(websocketsvr *server, websocketpp::connection_hdl hdl)
{
    cout << "连接成功" << endl;
}

// websocket连接成功的回调函数
void OnClose(websocketsvr *server, websocketpp::connection_hdl hdl)
{
    cout << "连接关闭" << endl;
}

// websocket连接收到消息的回调函数
void OnMessage(websocketsvr *server, websocketpp::connection_hdl hdl, message_ptr msg)
{
    cout << "收到消息" << msg->get_payload() << endl;
    // 收到消息将相同的消息发回给websocket客⼾端
    server->send(hdl,msg->get_payload(),websocketpp::frame::opcode::text);
}

int main()
{
    // 使⽤websocketpp库创建服务器
    websocketsvr server;
    // 设置websocketpp库的⽇志级别
    // all表⽰打印全部级别⽇志
    // none表⽰什么⽇志都不打印
    server.set_access_channels(websocketpp::log::alevel::none);
    /*初始化asio*/
    server.init_asio();
    // 注册http请求的处理函数
    server.set_http_handler(bind(&OnHttp, &server, ::_1));
    // 注册websocket请求的处理函数
    server.set_open_handler(bind(&OnOpen, &server, ::_1));
    server.set_close_handler(bind(&OnClose, &server, ::_1));
    server.set_message_handler(bind(&OnMessage, &server, ::_1, ::_2));
    // 监听8888端⼝
    server.listen(8888);
    // 开始接收tcp连接
    server.start_accept();
    // 开始运⾏服务器
    server.run();
    return 0;
}